package com.ssy.lingxi.platform.manage.serviceimpl.content;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.manage.entity.content.MemberInformation;
import com.ssy.lingxi.platform.manage.entity.content.MemberLabel;
import com.ssy.lingxi.platform.manage.entity.content.QMemberLabel;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdRequest;
import com.ssy.lingxi.platform.manage.model.request.common.CommonStatusRequest;
import com.ssy.lingxi.platform.manage.model.request.content.MemberLabelPageRequest;
import com.ssy.lingxi.platform.manage.model.request.content.MemberLabelRequest;
import com.ssy.lingxi.platform.manage.repository.MemberInformationRepository;
import com.ssy.lingxi.platform.manage.repository.MemberLabelRepository;
import com.ssy.lingxi.platform.manage.service.content.IMemberLabelService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 内容能力-标签管理
 * @author wyx
 * @version 2.0.0
 * @date 2021-09-28
 */
@Service
public class MemberLabelServiceImpl implements IMemberLabelService {

    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private MemberLabelRepository memberLabelRepository;
    @Resource
    private MemberInformationRepository memberInformationRepository;


    /**
     * 标签分页列表
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberLabel>> page(MemberLabelPageRequest request, UserLoginCacheDTO user) {
        //表实体
        QMemberLabel qMemberLabel = QMemberLabel.memberLabel;
        //构造查询条件
        BooleanBuilder predicates = new BooleanBuilder();

        predicates.and(qMemberLabel.memberId.eq(user.getMemberId()));
        predicates.and(qMemberLabel.memberRoleId.eq(user.getMemberRoleId()));
        if (StrUtil.isNotBlank(request.getName())) {
            predicates.and(qMemberLabel.name.like("%" + request.getName() + "%"));
        }

        JPAQuery<MemberLabel> query = jpaQueryFactory.select(qMemberLabel).from(qMemberLabel).where(predicates);

        long totalCount = query.fetchCount();

        List<MemberLabel> list = query.orderBy(qMemberLabel.id.desc())
                .offset(request.getCurrentOffset())
                .limit(request.getPageSize())
                .fetch();
        return Wrapper.success(new PageData<>(totalCount, list));
    }

    /**
     * 标签详情
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberLabel> get(CommonIdRequest request) {
        MemberLabel memberLabel = memberLabelRepository.findById(request.getId()).orElse(null);
        if (memberLabel == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        return Wrapper.success(memberLabel);
    }

    /**
     * 新增标签
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> add(MemberLabelRequest request, UserLoginCacheDTO user) {
        MemberLabel memberLabel = new MemberLabel();
        BeanUtils.copyProperties(request, memberLabel);
        memberLabel.setMemberId(user.getMemberId());
        memberLabel.setMemberRoleId(user.getMemberRoleId());
        memberLabelRepository.saveAndFlush(memberLabel);
        return Wrapper.success();
    }

    /**
     * 修改标签
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> update(MemberLabelRequest request, UserLoginCacheDTO user) {
        MemberLabel memberLabel = memberLabelRepository.findById(request.getId()).orElse(null);
        if (memberLabel == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (memberLabel.getStatus().equals(CommonBooleanEnum.YES.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        BeanUtils.copyProperties(request, memberLabel);
        memberLabelRepository.saveAndFlush(memberLabel);
        return Wrapper.success();
    }

    /**
     * 停用/启用
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> updateStatus(CommonStatusRequest request, UserLoginCacheDTO user) {
        //停用标签时, 需要先判断该标签是否被资讯信息所关联, 如果有则不能被停用
        if (request.getEnableStatus().equals(CommonBooleanEnum.NO.getCode())) {
            List<MemberInformation> all = memberInformationRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());
            if (CollectionUtil.isNotEmpty(all)) {
                if (all.stream().anyMatch(a -> a.getLabelIds().contains(request.getId()))) {
                    throw new BusinessException(ResponseCode.MAN_DATA_RELATION_INFORMATION);
                }
            }
        }

        MemberLabel memberLabel = memberLabelRepository.findById(request.getId()).orElse(null);
        if (memberLabel == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        memberLabel.setStatus(request.getEnableStatus());
        memberLabelRepository.saveAndFlush(memberLabel);
        return Wrapper.success();
    }

    /**
     * 删除标签
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> delete(CommonIdRequest request, UserLoginCacheDTO user) {
        //删除标签时, 需要先判断该标签是否被资讯信息所关联, 如果有则不能被停用
        List<MemberInformation> all = memberInformationRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());
        if (CollectionUtil.isNotEmpty(all)) {
            if (all.stream().anyMatch(a -> a.getLabelIds().contains(request.getId()))) {
                throw new BusinessException(ResponseCode.MAN_DATA_RELATION_INFORMATION);
            }
        }

        MemberLabel memberLabel = memberLabelRepository.findById(request.getId()).orElse(null);
        if (memberLabel == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (memberLabel.getStatus().equals(CommonBooleanEnum.YES.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        memberLabelRepository.delete(memberLabel);
        return Wrapper.success();
    }

    /**
     * 所有标签
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberLabel>> all(UserLoginCacheDTO user) {
        List<MemberLabel> memberLabelList = memberLabelRepository.findAllByMemberIdAndMemberRoleIdAndStatus(user.getMemberId(), user.getMemberRoleId(), CommonBooleanEnum.YES.getCode(), Sort.by("id"));
        return Wrapper.success(memberLabelList);
    }

    /**
     * 热门标签
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberLabel>> hot(UserLoginCacheDTO user) {
        //获取所有可用的标签, 再获取所有资讯, 筛选出有包含在资讯的标签
        List<MemberLabel> memberLabelList = memberLabelRepository.findAllByMemberIdAndMemberRoleIdAndStatus(user.getMemberId(), user.getMemberRoleId(), EnableDisableStatus.ENABLE.getCode(), Sort.by(Sort.Direction.DESC, "createTime"));
        memberLabelList = memberLabelList.stream()
                .filter(a -> memberInformationRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId())
                        .stream().anyMatch(b -> b.getLabelIds().contains(a.getId())))
                .collect(Collectors.toList());
        return Wrapper.success(memberLabelList);
    }
}
